<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>2_react生命周期(旧)</title>
  <!-- 引入React核心库 -->
  <script type="text/javascript" src="../js/react.development.js"></script>
  <!-- 引入react-dom,用于支持react操作DOM -->
  <script type="text/javascript" src="../js/react-dom.development.js"></script>
  <!-- 引入babel，用于把jsx转为js -->
  <script type="text/javascript" src="../js/babel.min.js"></script>
  <!-- 引入prop-types,用于对prop进行限制 -->
  <script type="text/javascript" src="../js/prop-types.js"></script>
</head>

<body>
  <div id="test1"></div>
  <div id="test2"></div>

  <script type="text/babel">
    /*
      1.初始化阶段：由ReactDOM.render()触发-----初次渲染
              1.constructor()
              2.componentWillMount()
              3.render()
              4.componentDidMount() ======>常用
                        一般在这个钩子中做一些初始化的事，例如：开启定时器、发送网络请求、订阅消息
      2.更新阶段：由组件内部this.setState()或父组件render触发
              1.shouldComponentUpdate()
              2.componentWillUpdate()
              3.render() ======>必须使用
              4.componentDidUpdate()
      3.卸载组件：由ReactDOM.unmountComponentAtNode()触发
              1.componentWillUnmount() =======>常用
                        一般这个钩子中做一些收尾的事，例如：关闭定时器、取消订阅消息
    */
    // 创建组件
    class Count extends React.Component {
      // 组件初始化一开始就加载
      constructor(props) {
        console.log('Count---constructor')
        super(props)
        this.state = {
          count: 0
        }
      }

      add = () => {
        const { count } = this.state
        this.setState({ count: count + 1 })
      }

      // 组件卸载
      death = () => {
        ReactDOM.unmountComponentAtNode(document.getElementById('test'))
      }

      // 组件强制更新
      force = () => {
        this.forceUpdate()
      }

      // 组件挂载前调用的钩子
      componentWillMount () {
        console.log('Count---componentWillMount')
      }
      // 组件挂载后调用的钩子
      componentDidMount () {
        console.log('Count---componentDidMount')
      }

      // 组件卸载前调用的钩子
      componentWillUnmount () {
        console.log('Count---componentWillUnmount')
      }

      // 控制组件更新的“阀门”，必须写返回值（true,false）
      shouldComponentUpdate () {
        console.log('Count---shouldComponentUpdate')
        return true
      }

      // 组件将要更新的钩子
      componentWillUpdate () {
        console.log('Count---componentWillUpdate')
      }
      // 组件更新完毕时调用的钩子
      componentDidUpdate () {
        console.log('Count---componentDidUpdate')
      }

      // 组件挂载
      render () {
        console.log('Count---render')
        const { count } = this.state
        return (
          <div>
            <h1>当前的和为{count}</h1>
            <button onClick={this.add}>+1</button>
            <button onClick={this.death}>卸载组件</button>
            <button onClick={this.force}>不更改状态中的数据，强制更新</button>
          </div>
        )
      }
    }
    // 父组件
    class A extends React.Component {
      state = {
        carName: '奔驰'
      }
      changeCar = () => {
        this.setState({ carName: '奥拓' })
      }
      render () {
        return (
          <div>
            <div>A</div>
            <button onClick={this.changeCar}>换车</button>
            <B carName={this.state.carName} />
          </div>
        )
      }
    }
    // 子组件
    class B extends React.Component {
      // 在子组件接收到新的props的时候调用的钩子（首次传入props时不触发）
      componentWillReceiveProps () {
        console.log('B----componentWillReceiveProps')
      }

      // 控制组件更新的“阀门”，必须写返回值（true,false）
      shouldComponentUpdate () {
        console.log('B---shouldComponentUpdate')
        return true
      }

      // 组件将要更新的钩子
      componentWillUpdate () {
        console.log('B---componentWillUpdate')
      }
      // 组件更新完毕时调用的钩子
      componentDidUpdate () {
        console.log('B---componentDidUpdate')
      }
      render () {
        return (
          <div>
            <div>B,接收到的车是：{this.props.carName}</div>
          </div>
        )
      }
    }

    // 渲染组件
    ReactDOM.render(<A />, document.getElementById('test1'))
    ReactDOM.render(<Count />, document.getElementById('test2'))
  </script>
</body>

</html>